Skip to content

feat/user-facing profile view and edit pages - #52

Merged
ethnjs merged 22 commits into
mainfrom
feat/profile-view-edit
Jul 25, 2026
Merged

feat/user-facing profile view and edit pages#52
ethnjs merged 22 commits into
mainfrom
feat/profile-view-edit

Conversation

@ethnjs

@ethnjs ethnjs commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Background

Users need a place to view their full profile and update it after the initial sign-up flow. The edit page reuses components from sign-up step 2 but as a flat form with current values pre-filled.

Changes

Backend

  • No model/schema changes in this PR — pronouns and date_of_birth already exist on User from the prior structured-experience PR
  • pronouns removed from the required-fields list in compute_missing_profile_fields() (app/core/profile_status.py) — no longer blocks profile completeness
  • Reads continue to go through UserMeSlimResponse/UserMeFullResponse (GET /users/me/ and GET /users/me/?full=true); admin read is GET /admin/users/{user_id}/ via UserFullResponse — none of these changed in this PR
  • GET /events/ (pre-existing route) is now actually consumed by the frontend for the competition-experience event picker

Frontend — /profile/[id] (profile view)

  • Route guard redirects to /dashboard if currentUser.id !== profileId (string-coerced comparison on both sides)
  • Fetches GET /users/me/?full=true on mount
  • Displays: basic info (name, pronouns, email, phone, DOB, student/employer branch), competition experience, volunteer experience — both experience tables render as flat lists in API order; no grouping by event or sorting by year yet
  • Floating "Edit profile" button links to /profile/[id]/edit
  • Separate edit icon in ProfileHeader links to /account-settings, which doesn't exist yet — placeholder for a later PR
  • Chapter membership tag and a locked/read-only indicator for NEXUS-sourced volunteer entries are planned for later PRs (chapter membership depends on alumni chapters work tracked in #42; locking depends on an is_locked-equivalent field that doesn't exist on UserVolunteerExperience yet)

Frontend — /profile/[id]/edit (edit profile)

  • Pre-fills all fields from GET /users/me/?full=true on mount
  • Basic info: name, pronouns, phone, is_student toggle with student (university/major/status) or non-student (employer) branch, shirt size, dietary restriction, date of birth
  • Experience flags: "I have no competition / volunteer experience" is a Yes/No radio (not a checkbox) that sets has_*_experience=false via PATCH /users/me/; unset fields are simply omitted from the PATCH body (dropped by the request serializer) rather than explicitly set to null, so under exclude_unset they're left unchanged, not reset
  • Competition experience: add/edit/delete entries, event picked via searchable dropdown sourced from GET /events/, fields are event, school, notes
  • Volunteer experience: add/edit/delete entries — all entries are currently editable the same way; no locked/read-only distinction for NEXUS-sourced entries yet (see above)
  • Basic info saved via PATCH /users/me/ (exclude_unset — only changed fields sent)
  • Reuses existing Input, Select, Textarea, RadioOption components, plus new profile-specific field components (see below)

Also included — supporting frontend changes

  • dashboard/layout.tsx deleted; AuthProvider moved up to the root layout, so non-dashboard routes like /profile/[id] can use auth context
  • New components: AvatarCircle, ProfileFields, and section components EducationCareerSection/LogisticsSection
  • UserAvatar rewritten to use AvatarCircle and adds a "Profile" menu item linking to /profile/[id]
  • Sign-up page substantially rewritten (716 lines) to extract and share the experience-table UI with the profile edit page

Also included — unrelated fixes swept into this range

  • Tailwind v4 theme tokens wired up; cascade-layer reset fix (styling infra); tailwind.config.ts removed
  • nexus_test database now auto-creates on a fresh Postgres volume (local dev infra)
  • Email-verification page now uses useAuth() instead of the removed authApi.me()
  • Combobox bug fix: an option that's fully typed but not explicitly selected from the dropdown wasn't being recognized
  • Backend/frontend test updates reflecting the nested event schema on experience responses

Testing

  • Manually walked profile view for a user with a full profile (all sections populated) and an incomplete one (banners/missing-field states)
  • Manually walked edit flow: pre-fill, basic info save, add/edit/delete on both experience tables, has-no-experience radio toggling correctly
  • Verified route guard redirects when viewing another user's /profile/[id]
  • Verified date_of_birth never appears in any response other than self-view (UserMeFullResponse only — not on the admin-facing UserFullResponse)
  • Confirmed branch builds/runs in isolation

Notes

  • date_of_birth is self-view only, never exposed to other users; a TD-facing view exposing only age-threshold booleans is deferred to a later issue
  • No individual GET routes for experience sub-tables — always read through GET /users/me/?full=true
  • Locked/read-only NEXUS-sourced volunteer entries and chapter membership tags are not implemented yet — flagged above as planned future work, not bugs
  • The unrelated fixes/infra commits listed above landed in this same commit stretch and are included here rather than split into their own PR, per prior pattern on this rewrite

ethnjs added 22 commits July 25, 2026 16:10
…er; wordmark in topbar is clickable and allows users to return to their dashboard
nexus_test previously only existed because it was created manually with a one-off createdb command, so dropping the postgres_data volume silently broke the test suite. Mount db-init/ to docker-entrypoint-initdb.d so Postgres creates it automatically on first container init, and update the README accordingly.
…t changes in schema where EventResponse is nested in experience responses and EventCategoryResponse is nested in event responses
…ail page

- authApi.me() and the User type were removed; user was only checked for truthiness anyway
- pulls user from the root-level AuthProvider (UserMeSlim) instead
…on an experience row in edit mode for spreadsheets in view-edit mode
@ethnjs ethnjs linked an issue Jul 25, 2026 that may be closed by this pull request
16 tasks
@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nexus Ready Ready Preview, Comment Jul 25, 2026 11:18pm

@railway-app
railway-app Bot temporarily deployed to nexus / nexus-pr-52 July 25, 2026 23:18 Destroyed
@ethnjs
ethnjs merged commit 2f0fba2 into main Jul 25, 2026
3 of 4 checks passed
@ethnjs
ethnjs deleted the feat/profile-view-edit branch July 25, 2026 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: profile and edit profile pages

1 participant